iT邦幫忙

2024 iThome 鐵人賽

DAY 19
0
JavaScript

JavaScript 基礎:端開發的第一步系列 第 19

非同步 JavaScript 與 Promise

  • 分享至 

  • xImage
  •  

第十九天:非同步 JavaScript 與 Promise

非同步編程可以讓我們在不阻塞主線程的情況下執行長時間的操作,比如讀取伺服器上的資料或處理計時器。Promise 是處理非同步操作的核心概念之一,它使得代碼更易讀且更具結構性。

1. 非同步操作

JavaScript 是單線程語言,這意味著它一次只能執行一件事。非同步操作允許我們在不阻塞應用的情況下處理耗時任務,比如資料請求、定時任務或 I/O 操作。

常見的非同步操作:
  • 伺服器請求(AJAX、fetch API)
  • 計時器(setTimeoutsetInterval
  • 事件處理(如用戶點擊、鍵盤輸入等)

2. Callback 函數

早期的 JavaScript 通常使用 Callback(回呼函數) 來處理非同步操作。回呼函數是當非同步操作完成時調用的函數,但過多的回呼可能會導致代碼難以維護,這種現象被稱為「回呼地獄」。

範例:
setTimeout(function() {
console.log("3 秒後執行此代碼");
}, 3000);

這種寫法在少量回呼的情況下可行,但一旦有多層嵌套,代碼就會變得混亂,難以維護。

3. Promise 概念

為了解決回呼地獄的問題,ES6 引入了 Promise。Promise 是一種用來處理非同步操作的物件,它允許我們更好地控制非同步流程。

Promise 有三種狀態:

  • pending(等待中):初始狀態,操作尚未完成。
  • fulfilled(已完成):操作成功完成。
  • rejected(已拒絕):操作失敗。

Promise 最終會解決為 fulfilledrejected,並且可以使用 thencatch 方法來處理成功和失敗的結果。

4. 創建 Promise

你可以使用 new Promise() 來創建一個 Promise,並在 Promise 內部執行非同步操作。

範例:
let promise = new Promise(function(resolve, reject) {
let success = true;

if (success) {
resolve("操作成功!");
} else {
reject("操作失敗!");
}
});

promise.then(function(result) {
console.log(result); // 當操作成功時,輸出 "操作成功!"
}).catch(function(error) {
console.log(error); // 當操作失敗時,輸出 "操作失敗!"
});

在這裡,resolvereject 是兩個回呼函數,分別用來通知 Promise 成功或失敗。根據不同的情況,我們可以在 then 中處理成功結果,或者在 catch 中捕獲錯誤。

5. then 和 catch

then 方法用於在 Promise 完成時執行某些操作,catch 則是當 Promise 被拒絕時執行錯誤處理。

範例:
fetch("https://api.example.com/data")
.then(function(response) {
return response.json();
})
.then(function(data) {
console.log("資料獲取成功:", data);
})
.catch(function(error) {
console.log("資料獲取失敗:", error);
});

在這個例子中,fetch 是一個返回 Promise 的方法,我們使用 then 來處理成功結果,並使用 catch 來處理錯誤。

6. Promise.all 與 Promise.race

  • Promise.all:當你有多個 Promise,需要等待所有 Promise 都完成時,可以使用 Promise.all。它會返回一個新的 Promise,當所有的 Promise 都完成時,這個新的 Promise 也會完成。

範例:
let promise1 = Promise.resolve(10);
let promise2 = Promise.resolve(20);

Promise.all([promise1, promise2]).then(function(results) {
console.log(results); // 輸出 [10, 20]
});

  • Promise.race:它會返回第一個完成的 Promise,而不管是成功還是失敗。

範例:
let slow = new Promise(resolve => setTimeout(resolve, 5000, "慢"));
let fast = new Promise(resolve => setTimeout(resolve, 1000, "快"));

Promise.race([slow, fast]).then(function(result) {
console.log(result); // 輸出 "快"
});

7. 使用 async/await

asyncawait 是基於 Promise 的語法糖,讓我們可以用同步的方式來寫非同步代碼,這使得代碼更清晰、更易於理解。

範例:
async function fetchData() {
try {
let response = await fetch("https://api.example.com/data");
let data = await response.json();
console.log("資料獲取成功:", data);
} catch (error) {
console.log("資料獲取失敗:", error);
}
}

fetchData();

在這個範例中,我們使用 await 來等待 fetch 完成,並通過 try/catch 來處理錯誤,這樣可以避免嵌套的 then/catch,使代碼更為簡潔。


上一篇
事件處理
下一篇
Promise
系列文
JavaScript 基礎:端開發的第一步30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言